home *** CD-ROM | disk | FTP | other *** search
- unit Editor;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- Menus, ToolWin, ComCtrls, StdCtrls,
- ImgList;
-
- type
- TResponse = (yes, no, cancel, nothing);
-
-
- TMainForm = class(TForm)
- EditWin: TRichEdit;
- MainMenu1: TMainMenu;
- FileMenu: TMenuItem;
- OpenMenuItem: TMenuItem;
- NewMenuItem: TMenuItem;
- N1: TMenuItem;
- SaveMenuItem: TMenuItem;
- SaveAsMenuItem: TMenuItem;
- N2: TMenuItem;
- ExitMenuItem: TMenuItem;
- EditMenu: TMenuItem;
- FindMenuItem: TMenuItem;
- ReplaceMenuItem: TMenuItem;
- UndoMenuItem: TMenuItem;
- ToolBar1: TToolBar;
- StatusBar: TStatusBar;
- OpenDialog: TOpenDialog;
- SaveDialog: TSaveDialog;
- CutMenuItem: TMenuItem;
- CopyMenuItem: TMenuItem;
- PasteMenuItem: TMenuItem;
- N3: TMenuItem;
- FontCombo: TComboBox;
- ShowFontStylesCB: TCheckBox;
- BoldBtn: TToolButton;
- ItalicBtn: TToolButton;
- ULineBtn: TToolButton;
- ToolIconsImageList: TImageList;
- ReplaceDialog: TReplaceDialog;
- FindDialog: TFindDialog;
- FontDialog: TFontDialog;
- FormatMenu: TMenuItem;
- FontMenuItem: TMenuItem;
- FontSizeCombo: TComboBox;
- ColourCombo: TComboBox;
- procedure NewMenuItemClick(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure OpenMenuItemClick(Sender: TObject);
- procedure ExitMenuItemClick(Sender: TObject);
- procedure SaveMenuItemClick(Sender: TObject);
- procedure SaveAsMenuItemClick(Sender: TObject);
- procedure CutMenuItemClick(Sender: TObject);
- procedure CopyMenuItemClick(Sender: TObject);
- procedure PasteMenuItemClick(Sender: TObject);
- procedure UndoMenuItemClick(Sender: TObject);
- procedure FontComboDrawItem(Control: TWinControl; Index: Integer;
- Rect: TRect; State: TOwnerDrawState);
- procedure ShowFontStylesCBClick(Sender: TObject);
- procedure FontComboChange(Sender: TObject);
- procedure EditWinSelectionChange(Sender: TObject);
- procedure BoldBtnClick(Sender: TObject);
- procedure ItalicBtnClick(Sender: TObject);
- procedure ULineBtnClick(Sender: TObject);
- procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- procedure FindMenuItemClick(Sender: TObject);
- procedure ReplaceMenuItemClick(Sender: TObject);
- procedure ReplaceDialogReplace(Sender: TObject);
- procedure FindDialogFind(Sender: TObject);
- procedure FontMenuItemClick(Sender: TObject);
- procedure FontSizeComboClick(Sender: TObject);
- procedure FontSizeComboExit(Sender: TObject);
- procedure FontSizeComboKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure FontSizeComboKeyPress(Sender: TObject; var Key: Char);
- procedure EditWinKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- procedure ColourComboDrawItem(Control: TWinControl; Index: Integer;
- Rect: TRect; State: TOwnerDrawState);
- procedure ColourComboChange(Sender: TObject);
- procedure EditWinKeyPress(Sender: TObject; var Key: Char);
- private
- { Private declarations }
- FFileName : string;
- // --- Save and Close
- procedure SetFileName( fn : string );
- procedure ClearEditWin;
- procedure DoSaveFile;
- function ConfirmFileSave( fn, msg : string) : TResponse;
- function OKtoCloseCurrentDoc : boolean;
- function SaveFileAs : TResponse;
- function SaveFile : TResponse;
- // --- Fonts and character styles
- procedure UpdateFontDisplay;
- procedure ToggleBold;
- procedure ToggleItalic;
- procedure ToggleULine;
- // --- Find and Replace routines
- function StrFoundAt( dlg : TFindDialog; Opts : TSearchTypes ) : LongInt;
- procedure FindStr( dlg : TFindDialog );
- function ReplaceStr( dlg : TReplaceDialog ) : boolean;
- function SearchOptions( dlg : TFindDialog ) : TSearchTypes;
- // ------------------------------
- public
- { Public declarations }
- end;
-
- // ColourID record
- ColourID = record
- Value : integer;
- Name : string;
- end;
-
- var
- MainForm: TMainForm;
-
- const
- NEWFILENAME = 'Untitled';
- APPNAME = 'Delphi Text Editor';
-
- FILEOVERWRITEMSG = '%s already exists. OK to overwrite?';
- FILESAVEMSG = 'Save changes to %s?';
-
- // typed constant - array of standard font sizes
- FONTSIZES : array[0..14] of integer =
- (8,9,10,11,12,16,18,20,22,24,26,28,36,48,72);
-
- // Lists the common colour constants. These will be used to init the
- // ColourCombo - NOTE: some routines assume that items in the array
- // and the combo are identical
- Colours: array[0..15] of ColourID = (
- (Value: clBlack; Name: 'clBlack'),
- (Value: clMaroon; Name: 'clMaroon'),
- (Value: clGreen; Name: 'clGreen'),
- (Value: clOlive; Name: 'clOlive'),
- (Value: clNavy; Name: 'clNavy'),
- (Value: clPurple; Name: 'clPurple'),
- (Value: clTeal; Name: 'clTeal'),
- (Value: clGray; Name: 'clGray'),
- (Value: clSilver; Name: 'clSilver'),
- (Value: clRed; Name: 'clRed'),
- (Value: clLime; Name: 'clLime'),
- (Value: clYellow; Name: 'clYellow'),
- (Value: clBlue; Name: 'clBlue'),
- (Value: clFuchsia; Name: 'clFuchsia'),
- (Value: clAqua; Name: 'clAqua'),
- (Value: clWhite; Name: 'clWhite'));
-
- // some space chars used to display colour in colourcombo
- COLOURBLOB = ' ';
-
- // ==========================================================================
- implementation
- // ==========================================================================
-
- {$R *.DFM}
- //--------------------------
- // --- Save/Load Routines
- //--------------------------
- function TMainForm.ConfirmFileSave( fn, msg : string ) : TResponse;
- var
- savechoice : integer;
- begin
- begin
- savechoice := MessageDlg(Format(FILESAVEMSG, [ExtractFileName(fn)]),
- mtConfirmation, mbYesNoCancel, 0);
- case savechoice of
- idYes: result := yes;
- idNo: result := no;
- idCancel: result := cancel;
- else result := nothing;
- end;
- end
- end;
-
- function TMainForm.OKtoCloseCurrentDoc : boolean;
- var
- doclose, dosave : TResponse;
- begin
- doclose := yes;
- dosave := no;
- if EditWin.Modified then
- case ConfirmFileSave( FFileName, FILESAVEMSG ) of
- yes: dosave := SaveFile;
- no, nothing : { do nothing } ;
- cancel : doclose := no;
- end;
- if (doclose = yes) and (dosave <> cancel) then
- result := true
- else
- result := false;
- end;
-
-
- procedure TMainForm.DoSaveFile;
- begin
- EditWin.Lines.SaveToFile(FFileName);
- EditWin.Modified := False;
- end;
-
-
- function TMainForm.SaveFileAs : TResponse;
- var
- saveit : TResponse;
- begin
- saveit := yes;
- if SaveDialog.Execute then
- begin
- if FileExists(SaveDialog.FileName) then
- saveit := ConfirmFileSave(SaveDialog.FileName, FILEOVERWRITEMSG);
- if saveit = yes then
- begin
- SetFileName(SaveDialog.FileName);
- DoSaveFile;
- end;
- end
- else saveit := cancel;
- result := saveit;
- end;
-
- function TMainForm.SaveFile : TResponse;
- var
- saveit : TResponse;
- begin
- saveit := yes;
- if FFileName = NEWFILENAME then
- saveit := SaveFileAs
- else
- DoSaveFile;
- result := saveit;
- end;
- // --- End Save/Load Routines
-
-
- //-------------------------------
- // --- Find and Replace Routines
- //-------------------------------
- function TMainForm.SearchOptions( dlg : TFindDialog ) : TSearchTypes;
- var
- opts : TSearchTypes;
- begin
- opts := [];
- if frWholeWord in dlg.Options then opts := opts + [stWholeWord];
- if frMatchCase in dlg.Options then opts := opts + [stMatchCase];
- end;
-
- function TMainForm.StrFoundAt( dlg : TFindDialog; Opts : TSearchTypes ) : LongInt;
- // this is adapted from Borland's code (in help)
- var
- FoundAt: LongInt;
- StartPos, ToEnd: integer;
- begin
- with EditWin do
- begin
- // begin the search after the current selection if there is one
- // otherwise, begin at the start of the text }
- if SelLength <> 0 then
- StartPos := SelStart + SelLength
- else
- StartPos := 0;
- // ToEnd is the length from StartPos to the end of the text
- // in the rich edit control
- ToEnd := Length(Text) - StartPos;
- FoundAt := FindText(dlg.FindText, StartPos, ToEnd, Opts );
- result := FoundAt;
- end;
- end;
-
-
- function TMainForm.ReplaceStr( dlg : TReplaceDialog ) : boolean;
- var
- FoundAt : LongInt;
- begin
- FoundAt := StrFoundAt( dlg, SearchOptions(dlg) );
- if FoundAt <> -1 then
- begin
- EditWin.SetFocus;
- // Select text --- same code as in FindStr()
- EditWin.SetFocus;
- EditWin.SelStart := FoundAt;
- EditWin.SelLength := Length(dlg.FindText);
- // Replace it
- EditWin.SelText := dlg.ReplaceText;
- // show selection
- EditWin.SelStart := FoundAt;
- EditWin.SelLength := Length(dlg.ReplaceText);
- end;
- if FoundAt <> -1 then
- result := true
- else
- result := false; // ret true if a replacement was made
- end;
-
- procedure TMainForm.FindStr( dlg : TFindDialog );
- var
- FoundAt : LongInt;
- begin
- FoundAt := StrFoundAt( dlg, SearchOptions(dlg) );
- if FoundAt <> -1 then
- begin
- EditWin.SetFocus;
- EditWin.SelStart := FoundAt;
- EditWin.SelLength := Length(dlg.FindText);
- end
- else MessageDlg('No match found', mtInformation, [mbOk], 0 );
- end;
- // --- end Find and Replace routines
-
-
- //-------------------------------
- // --- general utilty routines
- //-------------------------------
- procedure TMainForm.SetFileName( fn : string );
- begin
- FFileName := fn;
- Caption := Format('%s : [%s]', [APPNAME,ExtractFileName(fn)]);
- end;
-
- procedure TMainForm.ClearEditWin;
- // Clear out edit window and change various elements of the
- // environment as appropriate.
- begin
- EditWin.Lines.Clear;
- EditWin.Modified := False;
- SetFileName(NEWFILENAME);
- end;
- // --- end general utility routines
-
- //-------------------------------
- // --- Font and Character
- // --- style routines
- //-------------------------------
- procedure TMainForm.UpdateFontDisplay;
- var
- i, fontindex : integer;
- SelectedText : TTextAttributes;
- currCol : TColor;
- colindex : integer;
- begin
- SelectedText := EditWin.SelAttributes;
- // FONT
- // font combo
- fontindex := FontCombo.Items.IndexOf(SelectedText.Name);
- if fontindex <> -1 then
- FontCombo.ItemIndex := fontindex
- else
- FontCombo.ItemIndex := 0;
- // size combo
- FontSizeCombo.Text := IntToStr(SelectedText.Size);
- // colour combo
- currCol := SelectedText.Color;
- colindex := 0;
- for i := Low(Colours) to High(Colours) do
- if Colours[i].Value = currCol then colindex := i;
- ColourCombo.ItemIndex := colindex;
- //=================
- // STYLES
- BoldBtn.Down := fsBold in SelectedText.Style;
- ItalicBtn.Down := fsItalic in SelectedText.Style;
- ULineBtn.Down := fsUnderline in SelectedText.Style;
- end;
-
-
- procedure TMainForm.ToggleBold;
- // note the Style property of Tool buttons must be tbsCheck in order
- // that they stay down when clicked.
- var
- SelectedText : TTextAttributes;
- begin
- SelectedText := EditWin.SelAttributes;
- if BoldBtn.Down then
- SelectedText.Style := SelectedText.Style + [fsBold]
- else
- SelectedText.Style := SelectedText.Style - [fsBold];
- end;
-
- procedure TMainForm.ToggleItalic;
- var
- SelectedText : TTextAttributes;
- begin
- SelectedText := EditWin.SelAttributes;
- if ItalicBtn.Down then
- SelectedText.Style := SelectedText.Style + [fsItalic]
- else
- SelectedText.Style := SelectedText.Style - [fsItalic];
- end;
-
- procedure TMainForm.ToggleULine;
- var
- SelectedText : TTextAttributes;
- begin
- SelectedText := EditWin.SelAttributes;
- if ULineBtn.Down then
- SelectedText.Style := SelectedText.Style + [fsUnderline]
- else
- SelectedText.Style := SelectedText.Style - [fsUnderline];
- end;
-
- // --- End Font and Character style routines
-
-
- // ===================================================
- // =========== DELPHI-Managed Event Handlers ========
- // ===================================================
-
- //-------------------------------
- // --- Menus
- //-------------------------------
- procedure TMainForm.NewMenuItemClick(Sender: TObject);
- begin
- if OKtoCloseCurrentDoc then
- ClearEditWin;
- end;
-
- procedure TMainForm.OpenMenuItemClick(Sender: TObject);
- begin
- if OKtoCloseCurrentDoc then
- if OpenDialog.Execute then
- if not(FileExists(OpenDialog.FileName)) then
- MessageDlg(Format('Cannot open! %s not found.',[ExtractFileName(OpenDialog.FileName)]),
- mtInformation, [mbOK], 0)
- else
- begin
- EditWin.Lines.LoadFromFile(OpenDialog.FileName);
- SetFileName(OpenDialog.FileName);
- EditWin.SetFocus;
- EditWin.Modified := False;
- UpdateFontDisplay;
- end;
- end;
-
- procedure TMainForm.ExitMenuItemClick(Sender: TObject);
- begin
- Close;
- end;
-
- procedure TMainForm.SaveMenuItemClick(Sender: TObject);
- begin
- SaveFile;
- end;
-
- procedure TMainForm.SaveAsMenuItemClick(Sender: TObject);
- begin
- SaveFileAs;
- end;
-
- procedure TMainForm.CutMenuItemClick(Sender: TObject);
- begin
- EditWin.CutToClipboard;
- end;
-
- procedure TMainForm.CopyMenuItemClick(Sender: TObject);
- begin
- EditWin.CopyToClipboard;
- end;
-
- procedure TMainForm.PasteMenuItemClick(Sender: TObject);
- begin
- EditWin.PasteFromClipboard;
- end;
-
- procedure TMainForm.UndoMenuItemClick(Sender: TObject);
- begin
- EditWin.Undo;
- end;
-
- procedure TMainForm.FindMenuItemClick(Sender: TObject);
- begin
- FindDialog.Execute;
- end;
-
- procedure TMainForm.ReplaceMenuItemClick(Sender: TObject);
- begin
- ReplaceDialog.Execute;
- end;
-
- procedure TMainForm.FontMenuItemClick(Sender: TObject);
- begin
- // show currently selected editor font in Font dialog
- FontDialog.Font.Assign(EditWin.SelAttributes);
- // then execute FontDialog and apply chosen font (if there is one)
- if FontDialog.Execute then
- begin
- EditWin.SelAttributes.Assign(FontDialog.Font);
- // make sure that SelectionChange() updates font combo etc.
- UpdateFontDisplay;
- end;
- end;
- // --- End Menus
-
- //-------------------------------
- // --- Find & Replace Dialogs
- //-------------------------------
- procedure TMainForm.ReplaceDialogReplace(Sender: TObject);
- var
- repcount : integer;
- dlg : TReplaceDialog;
- begin
- repcount := 0;
- dlg := TReplaceDialog( Sender );
- if frReplaceAll in dlg.Options then
- begin
- while ReplaceStr( dlg ) do
- INC(repcount);
- ShowMessage( IntToStr(repcount) + ' replacements made.' );
- end
- else
- if not ReplaceStr( dlg ) then
- MessageDlg('No match found', mtInformation, [mbOk], 0 );
- end;
-
- procedure TMainForm.FindDialogFind(Sender: TObject);
- // This is shared by Replace and Find dialog
- begin
- FindStr( TFindDialog(Sender) );
- end;
- // --- End Find & Replace Dialogs
-
-
- //-------------------------------
- // --- COMBO BOXES
- //-------------------------------
-
- // --- Font Combo Box ---
- procedure TMainForm.FontComboDrawItem(Control: TWinControl; Index: Integer;
- Rect: TRect; State: TOwnerDrawState);
- begin
- with FontCombo.Canvas do
- begin
- FillRect(Rect);
- Font.Name := FontCombo.Items[Index];
- Font.Size := 12;
- TextOut(Rect.Left, Rect.Top, FontCombo.Items[Index]);
- end;
- end;
-
- procedure TMainForm.ShowFontStylesCBClick(Sender: TObject);
- begin
- if ShowFontStylesCB.checked then
- FontCombo.Style := csOwnerDrawFixed
- else
- FontCombo.Style := csDropDownList;
- end;
-
- procedure TMainForm.FontComboChange(Sender: TObject);
- begin
- EditWin.SelAttributes.Name := FontCombo.Items[FontCombo.ItemIndex];
- EditWin.SetFocus;
- end;
-
- // --- FontSize Combo ---
- procedure TMainForm.FontSizeComboClick(Sender: TObject);
- // mouse click selection of font size
- begin
- EditWin.SetFocus;
- end;
-
- procedure TMainForm.FontSizeComboExit(Sender: TObject);
- // deal with manual editing of the Font size
- var
- fsize : integer;
- begin
- fsize := StrToIntDef(FontSizeCombo.Text, -1);
- if fsize < 1 then
- begin
- MessageDlg(Format('Invalid Font size: %s.',[FontSizeCombo.Text]),
- mtInformation, [mbOK], 0);
- UpdateFontDisplay; // redisplay valid values in combos
- end
- else
- begin
- EditWin.SelAttributes.Size := StrToInt(FontSizeCombo.Text);
- EditWin.SetFocus;
- end;
- end;
-
- procedure TMainForm.FontSizeComboKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- begin
- // if Enter is pressed, focus editwin
- if Key = 13 then
- EditWin.SetFocus;
- end;
-
- procedure TMainForm.FontSizeComboKeyPress(Sender: TObject; var Key: Char);
- begin
- // without this, you'll hear an annoying 'ping!' when the Enter key is pressed
- if Key = #13 then Key := #0;
- end;
-
-
- // --- ColourCombo ---
- procedure TMainForm.ColourComboDrawItem(Control: TWinControl;
- Index: Integer; Rect: TRect; State: TOwnerDrawState);
- // Handle drawing of item that's selected on drop down
- begin
- with ColourCombo.Canvas do
- begin
- FillRect(Rect);
- Brush.Color := TColor(Colours[Index].Value);
- TextOut(Rect.Left, Rect.Top, COLOURBLOB);
- // ====
- Brush.Style := bsClear;
- TextOut(PenPos.X, Rect.Top, ' ' + Colours[Index].Name );
- end;
- end;
-
-
- procedure TMainForm.ColourComboChange(Sender: TObject);
- begin
- // This assumes that the index to items in Colours and ColourCombo is the same
- EditWin.SelAttributes.Color := Colours[ColourCombo.ItemIndex].Value;
- EditWin.SetFocus;
- end;
- // --- End Combo Boxes
-
- // -------------------------
- // --- ToolButtons
- // -------------------------
- procedure TMainForm.BoldBtnClick(Sender: TObject);
- begin
- ToggleBold;
- end;
-
- procedure TMainForm.ItalicBtnClick(Sender: TObject);
- begin
- ToggleItalic;
- end;
-
- procedure TMainForm.ULineBtnClick(Sender: TObject);
- begin
- ToggleULine;
- end;
- // --- End ToolButtons
-
-
- // -------------------------
- // --- EditWin
- // -------------------------
- procedure TMainForm.EditWinKeyUp(Sender: TObject; var Key: Word;
- Shift: TShiftState);
- var
- SelectedText : TTextAttributes;
- begin
- SelectedText := EditWin.SelAttributes;
- // Bold
- if (ssCtrl in Shift) and (upcase(chr(Key)) = 'B') then
- if fsBold in SelectedText.Style then
- SelectedText.Style := SelectedText.Style - [fsBold]
- else
- SelectedText.Style := SelectedText.Style + [fsBold];
- // Italic
- if (ssCtrl in Shift) and (upcase(chr(Key)) = 'I') then
- if fsItalic in SelectedText.Style then
- SelectedText.Style := SelectedText.Style - [fsItalic]
- else
- SelectedText.Style := SelectedText.Style + [fsItalic];
- // Underline
- if (ssCtrl in Shift) and (upcase(chr(Key)) = 'U') then
- if fsUnderline in SelectedText.Style then
- SelectedText.Style := SelectedText.Style - [fsUnderline]
- else
- SelectedText.Style := SelectedText.Style + [fsUnderline];
- UpdateFontDisplay;
- end;
-
- procedure TMainForm.EditWinKeyPress(Sender: TObject; var Key: Char);
- begin
- if Key = #9 then Key := #0;
- end;
-
- procedure TMainForm.EditWinSelectionChange(Sender: TObject);
- begin
- UpdateFontDisplay;
- end;
-
- // -------------------------
- // --- FORM Create and Close
- // -------------------------
- procedure TMainForm.FormCreate(Sender: TObject);
- var
- i : integer;
- begin
- ClearEditWin;
- EditWin.HideSelection := false; // show selection when EditWin loses focus
- // init FontCombo
- with FontCombo do
- begin
- Items := Screen.Fonts;
- ItemHeight := 20;
- Style := csDropDown;
- end;
- // init FontSize combo
- with FontSizeCombo do
- begin
- Style := csDropDown;
- for i := 0 to High(FontSizes) do
- Items.Add(IntToStr(FONTSIZES[i]));
- end;
- // init ColourCombo
- with ColourCombo do
- begin
- Style := csOwnerDrawVariable;
- for i := Low(Colours) to High(Colours) do
- Items.Add(COLOURBLOB + Colours[i].Name);
- end;
- UpdateFontDisplay; // indicate Font details in tools and combos of toolbar
- end;
-
- procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- begin
- if OKtoCloseCurrentDoc then
- CanClose := true
- else
- CanClose := false;
- end;
-
-
- end.
-